#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@desc: .

@Project ：kuberCloudTest 
@File ：vm_operation.py
@Author ：admin
@Date ：2024/3/20 16:49 
"""
from kuberCloudTest.cloud_resources.vms.urls import VMUrls
from kuberCloudTest.cloud_resources.vms.utils import vmUtils, BasicConf, ComputeResourceConf, StorageResourceConf, \
    NetworkResourceConf, get_create_vm_params
from kuberCloudTest.common.constant import OFFSET, LIMIT, AsyncType
from kuberCloudTest.common.utils import _getDetail, _getOperationType, _getLogAction
from kuberCloudTest.exception import KuberCloudException


def getVms(accessToken, **kwargs):
    """
    获取云主机
    :param accessToken: access token
    :param kwargs: offset:
                   limit:
                   keyword: xxx
                   order: asc|desc
                   searchType: 0: name; 1: ipv4; 2: physical machine uuid; 3: uuid; 5: owner; 6: ipv6
                   state: ''|starting|running|paused|stopping|stopped
                   labelId: label uuid
    :return:
    """
    params = {'offset': kwargs.get('offset', OFFSET),
              'limit': kwargs.get('limit', LIMIT),
              'searchtype': kwargs.get('searchType', 0),
              'keyword': kwargs.get('keyword', ''),
              'state': kwargs.get('state', ''),
              'order': kwargs.get('order', 'asc'),
              'labelId': kwargs.get('labelId', '')}
    vm_utils = vmUtils(accessToken=accessToken)
    return vm_utils.cloud_http_request.get(VMUrls.getVms.value, params)


def getVmDetail(accessToken, vmid):
    """
    获取云主机详情
    :param vmid: 云主机UUID
    :param accessToken: access token
    :return:
    """
    content = getVms(accessToken, searchType=3, keyword=vmid)
    total = content.get('total', 0)
    content = vmUtils(accessToken=accessToken).cloud_http_request.get(
        VMUrls.getVms.value, {'limit': total, 'offset': OFFSET, 'searchtype': 3})
    return _getDetail(content, vmid, 'vmid')


def createVm(accessToken,
             basicConf: BasicConf,
             computeResourceConf: ComputeResourceConf,
             storageResourceConf: StorageResourceConf, networkResourceConf: NetworkResourceConf):
    """
    创建云主机
    :param accessToken: access token
    :param basicConf: 基础资源配置参数
    :param computeResourceConf: 计算资源配置参数
    :param storageResourceConf: 存储资源配置参数
    :param networkResourceConf: 三层网络配置参数（此处不支持指定网络，系统自动分配）
    :return:
    """
    operationType = 1001
    data = _getOperationType(operationType, AsyncType.ASYNC.value)
    create_vm_params = get_create_vm_params(basicConf, computeResourceConf, storageResourceConf, networkResourceConf)
    data.update(create_vm_params)

    vm_utils = vmUtils(accessToken=accessToken)
    return vm_utils.cloud_http_request.post(VMUrls.createVm.value, data=data)


def deleteVm(accessToken, vmids):
    """
    删除云主机
    :param vmids: 云主机UUID(多个使用英文逗号分割)
    :param accessToken: access token
    :return:
    """
    operationType = 1008
    data = _getOperationType(operationType, AsyncType.ASYNC.value)
    data['ids'] = vmids
    vm_utils = vmUtils(accessToken=accessToken)
    return vm_utils.cloud_http_request.post(VMUrls.deleteVm.value, data=data)


def startVm(accessToken, vmids):
    """
    启用云主机
    :param vmids: 云主机UUID(多个使用英文逗号分割)
    :param accessToken: access token
    :return:
    """
    operationType = 1002
    data = _getOperationType(operationType, AsyncType.ASYNC.value)
    data['ids'] = vmids
    vm_utils = vmUtils(accessToken=accessToken)
    return vm_utils.cloud_http_request.post(VMUrls.startVm.value, data=data)


def stopVm(accessToken, vmids, unplugGpu=False):
    """
    停用
    :param vmids: 云主机UUID(多个使用英文逗号分割)
    :param unplugGpu: 卸载 gpu|vgpu
    :param accessToken: access token
    :return:
    """
    operationType = 1003
    data = _getOperationType(operationType, AsyncType.ASYNC.value)
    data['vmids'] = vmids
    data['unplugGpu'] = unplugGpu
    vm_utils = vmUtils(accessToken=accessToken)
    return vm_utils.cloud_http_request.post(VMUrls.stopVm.value, data=data)


def restartVM(accessToken, vmids):
    """
    重启云主机
    :param vmids: 云主机UUID(多个使用英文逗号分割)
    :param accessToken: access token
    :return:
    """
    operationType = 1004
    data = _getOperationType(operationType, AsyncType.ASYNC.value)
    data['ids'] = vmids
    vm_utils = vmUtils(accessToken=accessToken)
    return vm_utils.cloud_http_request.post(VMUrls.restartVM.value, data=data)


def updateVm(accessToken, vmid, name=None, remark=None):
    """
    更新云主机名称/描述
    :param accessToken: access token
    :param vmid: 云主机UUID
    :param name: 云主机名称
    :param remark: 描述
    :return:
    """
    content = getVmDetail(accessToken, vmid)
    vm = content['obj']
    if not vm:
        raise KuberCloudException('params error', 'vm [{}] not exist'.format(vmid))
    operationType = 1060
    data = _getLogAction(operationType, AsyncType.SYNC.value)
    data['vmid'] = vmid
    data['name'] = name if name else vm['name']
    data['remark'] = remark if remark else vm['remark']
    vm_utils = vmUtils(accessToken=accessToken)
    return vm_utils.cloud_http_request.post(VMUrls.updateVm.value, data=data)


def pauseVM(accessToken, vmids):
    """
    暂停云主机
    :param accessToken: access token
    :param vmids: 云主机UUID(多个使用英文逗号分割)
    :return:
    """
    operationType = 1006
    data = _getOperationType(operationType, AsyncType.ASYNC.value)
    data['ids'] = vmids
    vm_utils = vmUtils(accessToken=accessToken)
    return vm_utils.cloud_http_request.post(VMUrls.pauseVM.value, data=data)


def resumeVM(accessToken, vmids):
    """
    回复云主机
    :param accessToken: access token
    :param vmids: 云主机UUID(多个使用英文逗号分割)
    :return:
    """
    operationType = 1005
    data = _getOperationType(operationType, AsyncType.ASYNC.value)
    data['ids'] = vmids
    vm_utils = vmUtils(accessToken=accessToken)
    return vm_utils.cloud_http_request.post(VMUrls.resumeVM.value, data=data)


def forceStopVM(accessToken, vmids):
    """
    强制关闭云主机
    :param accessToken: access token
    :param vmids: 云主机UUID(多个使用英文逗号分割)
    :return:
    """
    operationType = 1007
    data = _getOperationType(operationType, AsyncType.ASYNC.value)
    data['ids'] = vmids
    vm_utils = vmUtils(accessToken=accessToken)
    return vm_utils.cloud_http_request.post(VMUrls.forceStopVM.value, data=data)


def resetVM(accessToken, vmids):
    """
    重置云主机
    :param accessToken: access token
    :param vmids: 云主机UUID(多个使用英文逗号分割)
    :return:
    """
    operationType = 1028
    data = _getOperationType(operationType, AsyncType.ASYNC.value)
    data['ids'] = vmids
    vm_utils = vmUtils(accessToken=accessToken)
    return vm_utils.cloud_http_request.post(VMUrls.resetVM.value, data=data)


def bindLabel(accessToken, vmid, labelIds):
    """
    云主机绑定标签
    :param accessToken: access token
    :param vmid: 云主机UUID
    :param labelIds: 标签UUID(多个使用英文逗号分割)
    :return:
    """
    operationType = 1047
    data = _getLogAction(operationType, AsyncType.SYNC.value)
    data['ids'] = labelIds
    params = {'vmid': vmid}
    vm_utils = vmUtils(accessToken=accessToken)
    return vm_utils.cloud_http_request.post(VMUrls.bindLabel.value, params=params, data=data)


def unbindLabel(accessToken, vmid, labelIds):
    """
    云主机解绑标签
    :param accessToken: access token
    :param vmid: 云主机UUID
    :param labelIds: 标签UUID(多个使用英文逗号分割)
    :return:
    """
    operationType = 1048
    data = _getLogAction(operationType, AsyncType.SYNC.value)
    data['ids'] = labelIds
    params = {'vmid': vmid}
    vm_utils = vmUtils(accessToken=accessToken)
    return vm_utils.cloud_http_request.post(VMUrls.unbindLabel.value, params=params, data=data)


def lockVm(accessToken, vmids):
    """
    锁定云主机
    :param accessToken: access token
    :param vmids: 云主机UUID(多个使用英文逗号分割)
    :return:
    """
    operationType = 1093
    data = _getOperationType(operationType, AsyncType.SYNC.value)
    data['ids'] = vmids
    vm_utils = vmUtils(accessToken=accessToken)
    return vm_utils.cloud_http_request.post(VMUrls.lockVm.value, data=data)


def unlockVm(accessToken, vmids):
    """
    解除锁定云主机
    :param accessToken: access token
    :param vmids: 云主机UUID(多个使用英文逗号分割)
    :return:
    """
    operationType = 1094
    data = _getOperationType(operationType, AsyncType.SYNC.value)
    data['ids'] = vmids
    vm_utils = vmUtils(accessToken=accessToken)
    return vm_utils.cloud_http_request.post(VMUrls.unlockVm.value, data=data)


def AddSSHKey(accessToken, vmid, sshKey: str):
    """
    云主机添加ssh-key
    :param accessToken: access token
    :param vmid: 云主机UUID
    :param sshKey: ssh-key
    :return:
    """
    if not sshKey.startswith('ssh-rsa'):
        raise KuberCloudException('params error', 'ssh-key startswith "ssh-rsa"')
    operationType = 1057
    data = _getOperationType(operationType, AsyncType.ASYNC.value)
    data['vmid'] = vmid
    vm_utils = vmUtils(accessToken=accessToken)
    return vm_utils.cloud_http_request.post(VMUrls.addSSHKey.value, data=data)


def removeSSHKey(accessToken, vmid):
    """
    云主机删除ssh-key
    :param accessToken: access token
    :param vmid: 云主机UUID
    :return:
    """
    operationType = 1058
    data = _getOperationType(operationType, AsyncType.ASYNC.value)
    data['vmid'] = vmid
    vm_utils = vmUtils(accessToken=accessToken)
    return vm_utils.cloud_http_request.post(VMUrls.removeSSHKey.value, data=data)


def updateClockMode(accessToken, vmid, clockMode):
    """
    更改云主机时钟模式
    :param accessToken: access token
    :param vmid: 云主机UUID
    :param clockMode: 时钟模式 utc|localtime
    :return:
    """
    operationType = 1069
    data = _getOperationType(operationType, AsyncType.ASYNC.value)
    data['vmid'] = vmid
    data['clockoffset'] = clockMode
    vm_utils = vmUtils(accessToken=accessToken)
    return vm_utils.cloud_http_request.post(VMUrls.updateClockMode.value, data=data)


def updateBiosMode(accessToken, vmid, biosMode):
    """
    更新云主机bios模式
    :param accessToken: access token
    :param vmid: 云主机UUID
    :param biosMode: bios模式 legacy|uefi
    :return:
    """
    operationType = 1095
    data = _getOperationType(operationType, AsyncType.ASYNC.value)
    data['vmid'] = vmid
    data['clockoffset'] = biosMode
    vm_utils = vmUtils(accessToken=accessToken)
    return vm_utils.cloud_http_request.post(VMUrls.updateBiosMode.value, data=data)


def changeMemoryBacking(accessToken, isHugePage: bool, vmid, hostId, hugePageId: str = '', hugePageSize: int = 0):
    """
    更新云主机内存大页
    :param accessToken: access token
    :param isHugePage: 是否更新云主机内存大页
    :param vmid: 云主机UUID
    :param hostId: 物理机UUID
    :param hugePageId: 内存大页UUID (isHugePage=True, hugePageId必填)
    :param hugePageSize: 内存大页大小 (isHugePage=True, hugePageSize必填)
    :return:
    """
    operationType = 1075
    data = _getOperationType(operationType, AsyncType.ASYNC.value)
    data['vmid'] = vmid
    data['hostId'] = hostId
    if isHugePage:
        if not hugePageId or not hugePageSize:
            raise KuberCloudException('params error', 'hugePageId or hugePageSize is none')
        data['hugePageId'] = hugePageId
        data['hugePageSize'] = hugePageSize
    data['hugePages'] = isHugePage
    vm_utils = vmUtils(accessToken=accessToken)
    return vm_utils.cloud_http_request.post(VMUrls.changeMemoryBacking.value, data=data)


def changeCPUQos(accessToken, vmid, globalPeriod: int = 100000, globalQuota: int = -1, shares: int = 1024):
    """
    更新云主机cpu-qos
    :param accessToken: access token
    :param vmid: 云主机UUID
    :param globalPeriod: CFS调用度器的时间间隔,取值范围[1000，1000000],单位是微秒，默认为0表示无，默认值是100000
    :param globalQuota: 周期内最大占用的时间,取值范围[1000,17592186044415],-1表示无限制，默认-1
    :param shares: CPU时间权重,取值范围[2,262144]默认值与操作系统有关，在平台中实测默认值是1024
    :return:
    """
    if globalPeriod not in range(1000, 1000000 + 1):
        raise KuberCloudException('params error', 'value range is [1000, 1000000]')
    if globalQuota not in range(1000, 17592186044415 + 1) or globalQuota != -1:
        raise KuberCloudException('params error', 'value range is [1000,17592186044415]')
    if shares not in range(2, 262144 + 1) or globalQuota != -1:
        raise KuberCloudException('params error', 'value range is [2,262144]')

    operationType = 1076
    data = _getOperationType(operationType, AsyncType.ASYNC.value)
    data['vmid'] = vmid
    data['globalperiod'] = globalPeriod
    data['globalquota'] = globalQuota
    data['shares'] = shares
    vm_utils = vmUtils(accessToken=accessToken)
    return vm_utils.cloud_http_request.post(VMUrls.changeCPUQos.value, data=data)


def configBlueScreenRestart(accessToken, vmid, isBlueScreenRestart: bool, qgaSyncTimeout: int):
    """
    云主机配置蓝屏重启
    :param accessToken: access token
    :param vmid: 云主机UUID
    :param isBlueScreenRestart: 云主机是否开启蓝屏重启
    :param qgaSyncTimeout: 监控蓝屏异常时间(秒),blueScreenRestart为true时必填
    :return:
    """
    operationType = 1084
    data = _getOperationType(operationType, AsyncType.ASYNC.value)
    data['vmid'] = vmid
    if isBlueScreenRestart:
        if not qgaSyncTimeout:
            raise KuberCloudException('params error', 'qgaSyncTimeout is none')
        data['qgaSyncTimeout'] = qgaSyncTimeout
    data['blueScreenRestart'] = isBlueScreenRestart
    vm_utils = vmUtils(accessToken=accessToken)
    return vm_utils.cloud_http_request.post(VMUrls.configBlueScreenRestart.value, data=data)


def configNuma(accessToken, vmid):
    """
    云主机配置numa
    :param accessToken: access token
    :param vmid: 云主机UUID
    :return:
    """
    operationType = 1072
    data = _getOperationType(operationType, AsyncType.ASYNC.value)
    data['vmid'] = vmid
    vm_utils = vmUtils(accessToken=accessToken)


def cancelNuma(accessToken, vmid):
    """
    取消云主机numa设置
    :param accessToken: access token
    :param vmid: 云主机UUID
    :return:
    """
    operationType = 1073
    data = _getOperationType(operationType, AsyncType.ASYNC.value)
    data['vmid'] = vmid
    vm_utils = vmUtils(accessToken=accessToken)
    return vm_utils.cloud_http_request.post(VMUrls.cancelNuma.value, data=data)


def changeUserPassword(accessToken, vmid, userName, password, confirmPassword):
    """
    更新云主机用户密码
    :param accessToken: access token
    :param vmid: 云主机UUID
    :param userName: 用户名
    :param password: 密码
    :param confirmPassword: 确认密码
    :return:
    """
    operationType = 1044
    data = _getOperationType(operationType, AsyncType.ASYNC.value)
    data['vmid'] = vmid
    data['userName'] = userName
    data['password'] = password
    data['confirmPassword'] = confirmPassword
    vm_utils = vmUtils(accessToken=accessToken)
    return vm_utils.cloud_http_request.post(VMUrls.changeUserPassword.value, data=data)


def setHA(accessToken, vmid, vmLevel: int, swch: bool = False):
    """
    云主机设置高可用
    :param accessToken: access token
    :param vmid: 云主机UUID
    :param vmLevel: 高可用级别(1:None, 2:NeverStop)
    :param swch: 是否随物理机启动
    :return:
    """
    operationType = 1073
    data = _getOperationType(operationType, AsyncType.ASYNC.value)
    data['vmid'] = vmid
    swch = True if vmLevel == 2 else swch
    swch = 1 if swch is True else 0
    data['vmlevel'] = vmLevel
    data['swch'] = swch
    vm_utils = vmUtils(accessToken=accessToken)
    return vm_utils.cloud_http_request.post(VMUrls.setHA.value, data=data)
